﻿/*jslint sloppy: true, devel: true, white: true*/
/*global $, $$, popup, handleAJAXExceptions */

///*
// *  Page onload
// */
//$(function () {
//    window.isIe8Browser = $.checkBrowser('IE', 8);
//    window.isMobileBrowser = jQuery.browser.mobile || /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
//    _informBrowserUpdates();
//    $.loadTooltip($('[title]'));
//});

$.extend({
    /*
     *  Send ajax request
     */
    ajaxRequest: function (options) {
        if (!$.isNotNull(options.url)) {
            return;
        }
        
        $.ajax({
            type: 'POST',
            cache: false,
            async: options.async === undefined ? true : options.async,
            url: options.url,
            data: options.data || { paramObjects: JSON.stringify(options.options) },
            contentType: options.contentType || 'application/x-www-form-urlencoded; charset=UTF-8', //client to server
            dataType: options.dataType || 'html', //server to client
            beforeSend: function () {
                if (typeof options.beforeSend === 'function') {
                    options.beforeSend.call(this);
                }

                //Create overlay progress
                if (options.overlay !== undefined) {
                    $(options.overlay).spin();
                } else {
                    //Create loading progress
                    if (options.showLoading !== undefined) {
                        popup.progress({
                            content: options.showLoading,
                            title: ''
                        });
                    }
                }
                /**********/
            },
            success: function (ajaxParams) {
                if (ajaxParams.error !== undefined) {
                    switch (ajaxParams.error) {
                        case 'update fail':
                            if (typeof options.error === 'function') {
                                options.error.call(this);
                            }
                            
                            //Remove loading progress
                            if (options.showLoading !== undefined) {
                                popup.close();
                                delete options.showLoading;
                            }
                            
                            popup.messageBox({
                                content: ajaxParams.content
                            });
                            break;
                        case 'timeout':
                            if (ajaxParams.content.length > 0) {
                                window.location = ajaxParams.content;
                            }
                            break;
                        default:
                            if (typeof options.success === 'function') {
                                //Remove loading progress
                                if (options.showLoading !== undefined) {
                                    popup.close();
                                    delete options.showLoading;
                                }
                                
                                options.success.call(this, ajaxParams.content || ajaxParams.Content);
                            }
                            break;
                    }
                } else {
                    //get data from Action Result
                    if (typeof ajaxParams === 'string') {
                        ajaxParams = $.trim(ajaxParams);
                    }
                    if (ajaxParams !== '' && typeof options.success === 'function') {
                        //Remove loading progress
                        if (options.showLoading !== undefined) {
                            popup.close();
                            delete options.showLoading;
                        }
                        
                        options.success.call(this, ajaxParams);
                    }
                }
            },
            error: function (jqXhr, exception) {
                handleAJAXExceptions(jqXhr, exception);
                if (typeof options.error === 'function') {
                    //Remove loading progress
                    if (options.showLoading !== undefined) {
                        popup.close();
                        delete options.showLoading;
                    }
                    
                    options.error.call(this);
                }
            },
            complete: function () {
                //Remove overlay progress
                if (options.overlay !== undefined) {
                    $(options.overlay).spin(false);
                } else {
                    //Remove loading progress
                    if (options.showLoading !== undefined) {
                        popup.close();
                    }
                }
                /**********/
                
                if (typeof options.complete === 'function') {
                    options.complete.call(this);
                }
            }
        });
    },
    /*
     *  Check browser version
     */
    checkBrowser: function (browserName, browserVersion) {
        var result = false;
        switch (browserName) {
            case "IE":
                result = $.browser.msie && parseInt($.browser.version, 10) === browserVersion;
                break;
            case 'Firefox':
                result = $.browser.mozilla;
                break;
        }
        return result;
    },
    /*
     *  Check session timeout when users click one server action
     */
    checkAuthentication: function (getSessionUrl, beforeSendFunc) {
        $.ajaxRequest({
            async: false,
            url: getSessionUrl || window.gGetSessionUrl,
            beforeSend: function () {
                if (typeof beforeSendFunc === 'function') {
                    beforeSendFunc.call(this);
                }
            },
            success: function (result) {
                if (result.data.length > 0) {
                    window.location = result.data;
                }
            }
        });
    },
    /*
     *  Get query value by name
     */
    getQueryParameterByName: function (parameterName) {
        parameterName = parameterName.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
        var regex = new RegExp("[\\?&(#/)]" + parameterName + "=([^&#]*)"),
            resultsArray = regex.exec(window.location.search + window.location.hash);
        if (resultsArray === null || !$.isNotNull(resultsArray[1])) {
            return null;
        }
        return decodeURIComponent(resultsArray[1].replace(/\+/g, " "));
    },
    /*
     *  Get higest z-index of Element on web page
     */
    getHiestZIndexOnPage: function () {
        var maxZindex = 0;

        $('*').each(function () {
            var elementZindex = parseInt($(this).css('z-index'));

            if (elementZindex > maxZindex) {
                maxZindex = elementZindex;
            }
        });

        return maxZindex;
    },
    /*
     *  Load html tooltip depend on title of elements
     */
    loadTooltip: function ($Elements) {
        //not show tooltip for mobile phone
        if (!window.isMobileBrowser && $Elements[0]) {
            var configTooltipClass = '',
                itemsSelector;
            
            if ($Elements.eq(0).is('area')) {
                configTooltipClass = 'ui-tooltip-area';
                itemsSelector = 'area[alt]';
            }
            
            $Elements.tooltip({
                track: true,
                content: function () {
                    var $element = $(this),
                        eleContent = $element.attr($element.is('area') ? 'alt' : 'title') || '';
                    
                    //Fix bug : not show tooltip if tooltip content contains ¤ character
                    if (eleContent.indexOf('¤') !== -1) {
                        eleContent = '';
                    }
                    
                    return eleContent;
                },
                items: itemsSelector || undefined,
                tooltipClass: configTooltipClass
            });
        }
    },
    /*
     *  Check object value is not null
     */
    isNotNull: function (value) {
        return value !== undefined && value !== null && value !== 'undefined' && value !== 'null';
    },
    /*
    *  Check Pattern REGEX
    */
    checkREGEX: function (pValue, pRegexFormat, pIgnoreCase) {
        var pRegexp;
        if (pIgnoreCase) {
            pRegexp = new RegExp(pRegexFormat, "i");
        } else {
            pRegexp = new RegExp(pRegexFormat);
        }
        return pRegexp.test(pValue);
    },
    /*
    *  Fix element position when scroll
    */
    applyFixedPositionScroll: function ($element, top, bottom) {
        $element.data('originalPos', { width: $element.width(), left: $element.offset().left });
        _applyFixedPosition($element, top, bottom);
        $(window).scroll(function () {
            _applyFixedPosition($element, top, bottom);
        });
    },
    /*
     *  Apply uniform for form controls
     */
    applyControlsUniform: function ($controlsContainer) {
        $controlsContainer = $controlsContainer || $('body');
        
        $controlsContainer.find('.radio-custom').click(function () {
            var $this = $(this);
            $controlsContainer.find('[data-group="' + $this.attr('data-group') + '"]').removeClass('selected');
            $this.toggleClass('selected');
        });
        
        $controlsContainer.find('.checkbox-custom').click(function () {
            $(this).toggleClass('selected');
        });
    },
    /*
    *  Sort array by name
    */
    sortArrayByName: function (arrayElements) {
        return arrayElements.sort(_sortByName);
    },
    /*
     *  Fix scroll on mobile
     */
    fixiScrollOnMobile: function (iScrollElement) {
        if (window.isMobileBrowser) {
            //Fix iScroll plugin, user can click on checkbox elements on mobile
            iScrollElement.options.onBeforeScrollStart = function (e) {
                var $target = $(e.target);
                while ($target[0].nodeType !== 1) {
                    $target = $target.parent();
                }
                if ($target.is(':checkbox')) {
                    return;
                }
                e.preventDefault();
            };
        }
    },
    /*
     *  Reset all controls to default value
     */
    resetControls:function ($controls) {
        $controls.each(function () {
            var $item = $(this);
            if($item.is('select')) {
                $('option:first', $item).attr('selected', true);
            }
        });
    },
    /*
     *  Check string is digit or not
     */
    isDigit:function (value) {
        // replace all an wanted chars and match.
        return /^[-+]?\d*$/.test($.trim(value.replace(/[,.']/g, '')));
    },
    /*
     *
     */
    isLongDate:function (value) {
        return value.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));
    },
    /*
     *  Debuging
     */
    benchmark: function (message, isBeginStart) {
        window.gBenchmarkStartTime = isBeginStart ? new Date() : (window.gBenchmarkStartTime || new Date());

        _log(message + " (" + (new Date().getTime() - window.gBenchmarkStartTime.getTime()) + " ms)");
    },
    /*
     *  Check user click on element object
     */
    isClickInElement: function (e, $elements) {
        var result = false;
        
        $elements.each(function() {
            var element = $(this)[0];
            if (element === e.target || (element && $.contains(element, e.target))) {
                result = true;
                return false; //exit loop
            }
            return true;
        });

        return result;
    },
    /*
     *  Go to another page
     */
    gotoPage: function (relativeUrl) {
        popup.progress({
            title: ''
        });

        window.location.href = relativeUrl;
    },
    getElementValues: function ($elements) {
        var values = [];
        $elements.each(function () {
            var $checkbox = $(this);
            if ($checkbox.attr('data-userid')) {
                values.push($checkbox.attr('data-userid'));
            } else {
                if ($checkbox.attr('data-departmentid')) {
                    values.push($checkbox.attr('data-departmentid'));
                } else {
                    values.push(this.value);
                }
            }
        });
        return values.join(',');
    },
    /*
     * Abort not complete ajax request
     */
    abortNotCompleteAjaxRequest:function(xhrList) {
        $.each(xhrList, function (i, xhrItem) {
            if ($.isNotNull(xhrItem) && xhrItem.readyState !== 4) {
                xhrItem.abort();
            }
        });
    },
    /*
     *  Render to top page icon
     */
    applyBackToTop: function () {
        $('body').append('<div class="to-top-button"><span class="glyphicon glyphicon-chevron-up"></span></div>');

        var $topButton = $('.to-top-button').click(function () {
            $('html, body').animate({ scrollTop: 0 }, window.gEffectDuration);
        }),
            $window = $(window);

        $window.scroll(function () {
            var windowScrollTop = $window.scrollTop();
            if (windowScrollTop > 60) {
                if ($topButton.css('display') === 'none') {
                    $topButton.fadeIn(window.gEffectDuration);
                }

            } else {
                if ($topButton.css('display') !== 'none') {
                    $topButton.fadeOut(window.gEffectDuration);
                }
            }
        }).trigger('scroll');
    },
    /*
     *  Apply group toggle
     */
    applyGroupToggle: function ($elements) {
        $elements.click(function() {
            $elements.removeClass('selected');
            $(this).addClass('selected');
        });
    }
});

function _log(s) {
    if (typeof console !== "undefined" && typeof console.debug !== "undefined") {
        console.log(s);
    } else {
        alert(s);
    }
}

/*
 *  disable text highlighting
 */
$.extend(
    /*
     *  Get outerHTML
     */
    $.fn.outerHTML = function ($Element) {
        return $Element ? this.before($Element).remove() : $("<p>").append(this.eq(0).clone()).html();
    },
    $.fn.disableTextSelect = function () {
        return this.each(function () {
            if ($.browser.mozilla) {//Firefox
                $(this).css('MozUserSelect', 'none');
            } else if ($.browser.msie) {//IE
                $(this).on('selectstart', function () { return false; });
            } else {//Opera, etc.
                $(this).mousedown(function () { return false; });
            }
        });
    },
    $.fn.hasScrollBar = function () {
        return this.get(0).scrollHeight > this.height();
    },
    /*
     *  Load scroll on mobile devices
     */
    $.fn.applyiScroll = function (scrollName, $lastItem) {
        if (window.isMobileBrowser) {
            if (window[scrollName] !== undefined) {
                window[scrollName].destroy();
                window[scrollName] = undefined;
            } else {
                //Must add relative position for iScroll container
                this.css('position','relative');
            }
            window[scrollName] = new iScroll(this[0], {
                hideScrollbar: true,
                hScroll: false
            });
            if ($lastItem) {
                window[scrollName].scrollToElement($lastItem[0], window.gEffectDuration);
            }
        } else {
            this.animate({ scrollTop: $lastItem ? $lastItem.position().top : 0 }, window.gEffectDuration);
        }
    }
);
/* ============================================================================== */

//This will sort your array
function _sortByName(a, b) {
    var aName = $(a).text().toLowerCase(),
        bName = $(b).text().toLowerCase();
    return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
}

function _applyFixedPosition($element, top, bottom) {
    var $window = $(window),
        windowScrollTop = $window.scrollTop(),
        originalData = $element.data('originalPos');
    if (top !== undefined && windowScrollTop > top) {
        $element.css({
            position: 'fixed',
            top: 0,
            width: originalData.width,
            left: originalData.left
        });
    } else {
        if (bottom !== undefined && windowScrollTop + $window.height() < bottom) {
            $element.css({
                position: 'fixed',
                bottom: 0,
                width: originalData.width,
                left: originalData.left
            });
        } else {
            //reset
            $element.css({
                position: '',
                top: '',
                bottom: '',
                width: '',
                left: ''
            });
        }
    }
}

/*
 *  Default handle errors
 */
$.ajaxSetup({
    error: function (jqXhr, exception) {
        handleAJAXExceptions(jqXhr, exception);
    }
});
function handleAJAXExceptions(jqXhr, exception) {
    if (jqXhr.status === 0 || jqXhr.readyState === 0 || exception === 'abort') {
        return;
    }
    var errorUrl = window.baseUrl + '/Errors/';
    switch (jqXhr.status) {
        case 404:
            window.open(errorUrl + 'NotFound?error=NotFound', '_self');
            break;
        case 403:
            window.open(errorUrl + 'AccessDenied?error=AccessDenied', '_self');
            break;
        case 512:
        case 513:
        case 514:
            window.open(window.baseUrl + '/Account/MaintenanceAnnounce', '_self');
            break;
        case 515:
            window.open(window.baseUrl + '/Account/Maintenance', '_self');
            break;
        case 516:
            window.open(window.baseUrl + '/Admin/ReturnGraduates', '_self');
            break;
        case 517:
            window.open(window.baseUrl + '/Admin/AdminGroupList', '_self');
            break;
        case 518:
            window.open(window.baseUrl + '/Admin/PrepareNewYear', '_self');
            break;
        case 519:
            window.open(window.baseUrl + '/Account/LogOff', '_self');
            break;
        case 520:
            window.open(window.baseUrl + 'UnTrustedUrl?error=UnTrustedUrl', '_self');
            break;
        default:
            window.open(errorUrl + 'General?error=General', '_self');
    }
}

/*
*  Bind text box focus event, fix for Chrome browser
*/
function bindFocusTextboxEvents(pParamInputCtrls) {
    pParamInputCtrls.click(function () {
        var pParamInput = $(this);
        if (pParamInput.attr('isfocus') === undefined) {
            this.select();
            pParamInput.attr('isfocus', 'true');
        }
    }).blur(function () {
        $(this).removeAttr('isfocus');
    });
}

//disable text highlighting on double click
function disableDoubleClickTextHighlight(pParamTable) {
    if (!$('not(thead)', pParamTable)[0]) {
        $('tbody > tr:first > td', pParamTable).disableTextSelect();
    } else {
        $('th', pParamTable).disableTextSelect();
    }
}

/*
 *  Check and inform users about browser-updates
 */
function _informBrowserUpdates() {
    window.$buoop = {
        vs: window.gVersionConfig || { i: 8, f: 15, o: 10.6, s: 4, n: 9 },
        reminder: 0, // atfer how many hours should the message reappear
        // 0 = show all the time
        // overrides the default detection
        //test:false, // true = always show the bar (for testing)
        text: window.gTxtBrowserUpdate, // custom notification html text
        newwindow: true // open link in new window/tab
    };

    window.$bu = $buo(window.$buoop || {});
}

